package com.oocl.euc.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;

public class XMLUtil {

    private XMLUtil() {
    }

    private static Logger logger = LoggerFactory.getLogger(XMLUtil.class);

    private static final String LOG_JAXBEXCEPTION="JAXBException";

    private static final String LOG_IOEXCEPTION="IOException";

    /**
     * Convert object to xml formated string
     *
     * @param obj
     * @return
     */
    public static String convertToXmlStr(Object obj) {
        String xmlStr = null;
        StringWriter stringWriter = null;
        try {
            Marshaller marshaller = getJaxbContext(obj.getClass()).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            stringWriter = new StringWriter();
            marshaller.marshal(obj, stringWriter);
            xmlStr = stringWriter.toString();
        } catch (JAXBException e) {
            logger.error(LOG_JAXBEXCEPTION, e);
        } finally {
            try {
                if (null != stringWriter) {
                    stringWriter.close();
                }
            } catch (IOException e) {
                logger.error(LOG_IOEXCEPTION, e);
            }
        }
        return xmlStr;
    }

    /**
     * Convert object to xml file
     *
     * @param obj
     * @param path
     */
    public static void convertToXmlFile(Object obj, String path) {
        FileWriter fileWriter = null;
        try {
            Marshaller marshaller = getJaxbContext(obj.getClass()).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            fileWriter = new FileWriter(path);
            marshaller.marshal(obj, fileWriter);
        } catch (JAXBException e) {
            logger.error(LOG_JAXBEXCEPTION, e);
        } catch (IOException e) {
            logger.error(LOG_IOEXCEPTION, e);
        } finally {
            try {
                if (null != fileWriter) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                logger.error(LOG_IOEXCEPTION, e);
            }
        }
    }

    /**
     * Convert xmlStr to object
     *
     * @param clazz
     * @param xmlStr
     * @return
     */
    public static Object convertXmlStrToObj(Class clazz, String xmlStr) {
        Object obj = null;
        StringReader stringReader = null;
        try {
            Unmarshaller unmarshaller = getJaxbContext(clazz).createUnmarshaller();
            stringReader = new StringReader(xmlStr);
            obj = unmarshaller.unmarshal(stringReader);
        } catch (JAXBException e) {
            logger.error(LOG_JAXBEXCEPTION, e);
        } finally {
            if (null != stringReader) {
                stringReader.close();
            }
        }
        return obj;
    }

    /**
     * Convert xml file to object
     *
     * @param clazz
     * @param path
     * @return
     */
    public static Object convertXmlFileToObj(Class clazz, String path) {
        Object obj = null;
        FileReader fileReader = null;
        try {
            Unmarshaller unmarshaller = getJaxbContext(clazz).createUnmarshaller();
            fileReader = new FileReader(path);
            obj = unmarshaller.unmarshal(fileReader);
        } catch (JAXBException e) {
            logger.error(LOG_JAXBEXCEPTION, e);
        } catch (FileNotFoundException e) {
            logger.error("FileNotFoundException", e);
        } finally {
            if (null != fileReader) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    logger.error(LOG_IOEXCEPTION, e);
                }
            }
        }
        return obj;
    }


    private static JAXBContext getJaxbContext(Class clazz) throws JAXBException {
        return JAXBContext.newInstance(clazz);
    }
}
